home *** CD-ROM | disk | FTP | other *** search
-
- /* ************************* */
- /* Multi-threading functions */
-
- #include <setjmp.h>
- #define TSTACKSIZE 200 /* Stack space reseved in each thread in words */
- #define MAXTHREAD 20 /* Max No of concurrent threads */
- #define SPINDX 1 /* Index of stack pointer into env */
- #define NULL 0
- static struct threaddat {
- int *env ; /* Environment pointer */
- int (*tfp)() ; /* Thread function pointer */
- int state ; /* 0 Waiting 1 running -1 terminated */
- } threaddata[MAXTHREAD] ;
- /* Globals for thread() */
- static jmp_buf envroot ; /* root environment */
- static int threadnum = -1 ; /* Number of threads */
- static int threadindx ; /* Thread indexer */
- /* Takes a NULL terminated list of function pointers, sets up
- the global parameters above and the root environment and then
- calls threadrun() to define and run the function threads. */
- thread(fplist)
- int (*fplist)() ;
- {
- int (**fplptr)() ;
- void threadrun() ;
- if (threadnum == -1)
- { fplptr = &fplist ;
- threadnum = 0 ;
- while (*fplptr != NULL)
- threaddata[threadnum++].tfp = *fplptr++ ;
- threadindx = 0 ;
- if (!setjmp(envroot))
- threadrun() ; /* define thread environments recursivly */
- /* then run them to extinction */
- }
- }
- /* recusivly defines thread environments then runs in round robin */
- void threadrun()
- {
- jmp_buf envthread ;
- int stackspace[TSTACKSIZE] ;
- if (threadindx < threadnum)
- { if (setjmp(envthread))
- { /* Will arrive here by longjmp for function dispatch */
- (*threaddata[threadindx].tfp)() ; /* Start thread */
- threaddata[threadindx].state = -1 ; /* terminated */
- threadswitch() ;
- printf("Multi-threading error - terminating ) ;
- exit(1) ;
- }
- else
- {
- /* Global pointer to thread env */
- threaddata[threadindx].env = envthread ;
- /* Thread state to waiting to run */
- threaddata[threadindx].state = 0 ;
- /* Modify env value for stack with a little margin for luck */
- envthread[SPINDX] = (int) &stackspace[TSTACKSIZE-5] ;
- threadrun(++threadindx) ; /* Recusive call for next thread env */
- }
- }
- else /* Run threads in round robin */
- {
- /* Start the ball rolling with thread 1*/
- threadindx = 0 ;
- longjmp(threaddata[threadindx].env, -1) ;
- }
- }
- /* Thread switcher : Will switch to next available function thread in list.
- If function threads have all terminated will terminate the threads
- environment and return to the root enviroment */
- threadswitch()
- { int i ;
- if (threadnum != -1)
- {
- if (threaddata[threadindx].state != -1)
- threaddata[threadindx].state = 0 ;
- if (!setjmp(threaddata[threadindx].env))
- {
- for (i=1; i <= threadnum; i++)
- { if (++threadindx >= threadnum)
- threadindx = 0 ;
- if (!threaddata[threadindx].state)
- { threaddata[threadindx].state = 1 ;
- longjmp(threaddata[threadindx].env, -1) ;
- }
- }
- threadnum = -1 ;
- longjmp(envroot, -1) ;
- }
- }
- }
-
-
-